package com.tianyi.lib.util;

import com.alibaba.fastjson.JSON;
import com.tianyi.lib.model.RpcResult;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class HttpClientUtils {

    private static final Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);
    private static final String DEFAULT_CHARSET = "UTF-8";
    private static final int DEFAULT_TIMEOUT = 5000;
    private static final int DEFAULT_CONNECT_TIMEOUT = 5000;


    public static <T> RpcResult<String> getDataFromPostEntity(String url, T entity, Map<String, String> header, int timeout, int retryCount){
        RpcResult<String> result = new RpcResult<>();
        int count = 0;
        while (count <= retryCount){
            try {
                String data = postEntity(url, entity, header, timeout);
                result.setData(data);
                result.setSuccess(true);
                return result;
            }catch (Exception e){
                e.printStackTrace();
                result.setSuccess(false);
                result.setException(e);
            }
            ++count;
        }
        return result;
    }

    /**
     * post 请求
     *
     * @param url           请求路径
     * @param entity        请求体
     * @param header        请求头
     * @param timeout       毫秒级
     * @param <T>
     * @return
     */
    private static <T> String postEntity(String url, T entity, Map<String, String> header, int timeout){

        String entityJson = JSON.toJSONString(entity);
        HttpClient httpClient = new HttpClient();
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
        httpClient.getParams().setSoTimeout(timeout);
        PostMethod postMethod = setPostEntityHeader(url, header);
        String result = "";
        try{
            postMethod.setRequestEntity(new StringRequestEntity(entityJson, "application/json", "UTF-8"));
            int status = httpClient.executeMethod(postMethod);
            if (status != 200){
                throw new RuntimeException("");
            }
            result = new String(postMethod.getResponseBody(), "UTF-8");
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    public static PostMethod setPostEntityHeader(String url, Map<String, String> header){

        PostMethod postMethod = new PostMethod(url);
        postMethod.setRequestHeader("Content-Type", "application/json;charset=utf-8");
        setHeader(header, postMethod);
        return postMethod;
    }

    public static void setHeader(Map<String, String> header, PostMethod method){
        if (MapUtils.isNotEmpty(header)){
            Iterator<Map.Entry<String, String>> iterator = header.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<String, String> next = iterator.next();
                method.setRequestHeader(next.getKey(), next.getValue());
            }
        }
    }


    public static <T> RpcResult<String> getDataFromGetMethod(String url, Map<String, String> entity, int timeout, int retryCount){
        RpcResult<String> result = new RpcResult<>();
        int count = 0;
        while (count <= retryCount){
            try {
                String data = sendByGetMethod(url, entity, timeout);
                result.setData(data);
                result.setSuccess(true);
                return result;
            }catch (Exception e){
                e.printStackTrace();
                result.setSuccess(false);
                result.setException(e);
            }
            ++count;
        }
        return result;
    }

    public static <T> String sendByGetMethod(String url){

        String sendByGetMethod = sendByGetMethod(url, null, 10000);
        return sendByGetMethod;
    }
    public static <T> String sendByGetMethod(String url, int timeout){

        String sendByGetMethod = sendByGetMethod(url, null, timeout);
        return sendByGetMethod;
    }


    /**
     * get 请求  返回相应json字符串
     * @param url           请求地址
     * @param entity        请求参数
     * @param timeout       毫秒数
     * @return
     */
    public static String sendByGetMethod(String url, Map<String, String>  entity, int timeout){

        url = verbGetMethodParam(url, entity);
        HttpClient httpClient = new HttpClient();
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
        httpClient.getParams().setSoTimeout(timeout);

        GetMethod method = new GetMethod(url);
        String result = "";
        try{
            int status = httpClient.executeMethod(method);
            if (status != 200){
                throw new RuntimeException("");
            }
            result = new String(method.getResponseBody(), "UTF-8");
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 拼接get请求url
     *
     * @param url
     * @param entity
     * @return
     */
    public static String verbGetMethodParam(String url, Map<String, String> entity){

        if (!StringUtils.contains(url, "?")){

            url = url+"?";
        }

        if (MapUtils.isEmpty(entity)){
            return url;
        }
        StringBuilder builder = new StringBuilder();

        Iterator<Map.Entry<String, String>> iterator = entity.entrySet().iterator();

        while (iterator.hasNext()) {

            Map.Entry<String, String> next = iterator.next();
            String key = next.getKey();
            String value = next.getValue();
            builder.append(key).append("=").append(value);
            builder.append("&");
        }

        builder.deleteCharAt(builder.length()-1);

        return url+builder.toString();
    }

    /**
     * json字符串转对象
     * @param objStr
     * @param clz
     * @param <T>
     * @return
     */
    public static <T> T parseJsonStr2Obj(String objStr, Class<T> clz){
        if (StringUtils.isBlank(objStr) || clz == null){
            return null;
        }
        try {
            T parseObject = JSON.parseObject(objStr, clz);
            return parseObject;
        }catch (Exception e){

            logger.info("parseJsonStr2Obj error {}", e.getMessage());
            return null;
        }
    }

    public static <T> List<T> parseJsonStr2List(String objStr, Class<T> clz){
        if (StringUtils.isBlank(objStr) || clz == null){
            return null;
        }
        try {

            return JSON.parseArray(objStr, clz);
        }catch (Exception e){

            logger.info("parseJsonStr2List error {}", e.getMessage());
            return null;
        }
    }




}
